package com.cat.paxos.learner;

import com.cat.paxos.acceptor.ConfirmProposalResponse;
import com.cat.paxos.common.Response;
import com.cat.paxos.proposal.ProposalNumberComparator;

import java.util.Comparator;
import java.util.List;

/**
 * @auther Cat.wang
 * @date 2020/1/16 17:01
 */
public class HalfUpLeanerStrategy implements LeanerStrategy {

    /**
     * 提案编号比较器
     */
    private Comparator<String> proposalNumberComparator = ProposalNumberComparator.DEFAULT_PROPOSAL_NUMBER_COMPARATOR;


    @Override
    public boolean decisionProposalNumberOk(String maxProposalNumber, String propsalNumber) {
        return maxProposalNumber == null || proposalNumberComparator.compare(propsalNumber, maxProposalNumber) >= 0;
    }

    @Override
    public ConfirmProposalResponse decisionLeanProposal(int total, List<LearnProposalResponse> responses) {

        boolean oked = responses.stream().filter(Response::ok).count() >= total / 2;
        String proposalNumbered;
        if (oked) {
            proposalNumbered = responses.stream().filter(Response::ok).map(LearnProposalResponse::proposalNumber).max(proposalNumberComparator).orElse(null);
        } else {
            proposalNumbered = responses.stream().map(LearnProposalResponse::proposalNumber).max(proposalNumberComparator).orElse(null);
        }

        return new ConfirmProposalResponse() {

            private String proposalNumber = proposalNumbered;

            private boolean ok = oked;

            @Override
            public String proposalNumber() {
                return proposalNumber;
            }

            @Override
            public boolean ok() {
                return ok;
            }
        };
    }
}
